<?php
/**
 * Created by PhpStorm.
 * User: Usr
 * Date: 2018/6/21
 * Time: 8:20
 */

require_once 'config.php';
require_once 'pub.php';
require 'Storage.php';

$storage = new Storage($tempfs, 'xata'); // 实例化Storage
// 分支目录
$s_dir = ['mast' => '/Zdata/wwwroot/xata_s/src', 'dev' => '/Zdata/wwwroot/xata_s/dev'];

echo "启动中……\n";


$server = new swoole_websocket_server('0.0.0.0', 9902);
$server->set(array(
    'worker_num' => 1, // 工作进程数量
    'task_worker_num' => 1, // 异步任务进程数量
    'pid_file' => __DIR__ . '/server.pid',
    'daemonize' => 1, // 进程守护模式
));

$server->on("request", function ($request, $response) use ($server) {
    $request_uri = ltrim($request->server['request_uri'], '/');
    // 过滤浏览器icon请求
    if ($request_uri === 'favicon.ico') {
        return $response->end("");
    }

    // 请求参数
    if ($request->server['request_method'] === 'POST') {
        $params = $request->post;
    } else {
        $params = $request->get;
    }
    $response = [];
    switch ($request_uri) {
        case 'checkFd': // 验证fd标识
            $response = [
                'status' => $server->exist(intval($params['fd']))
            ];
            break;
    }

    $response->end(json_encode($response));

});

$server->on('open', function ($server, $req) use ($s_dir) {
    // 客户端连接示例
    // var ws = new WebSocket('ws://' + '192.168.168.168:9901' + '/f739cI5M6gbzGfS2950J2MF0wVnygHDfGRA6gvTeNQ/stat');
    preg_match('/\/([a-zA-Z0-9+\/]*)\/([a-zA-Z_]*)/', $req->server['request_uri'], $request, PREG_OFFSET_CAPTURE);
    if (!isset($request[1][0]) || empty($request[2][0])) {
        echo '参数获取有误:' . $req->server['request_uri'] . PHP_EOL;
        return;
    }

    $fd = $req->fd;
    $sn = $request[1][0];

    if ($sn != 'f739cI5M6gbzGfS2950J2MF0wVnygHDfGRA6gvTeNQ') { // 签名认证失败，断开连接
        $server->close($fd);
    }

    switch ($request[2][0]) {
        case 'stat': // WEB端连接成功，把fd加入队列
            $stat_fd = $server->storage->get('stat/fd2');
            $stat_fd[] = $fd;
            $server->storage->set('stat/fd2', $stat_fd);
            msgToClient($fd, 'open', ['msg' => '监控服务器连接成功', 'data'=>array_keys($s_dir)]);

            // 循环所有分支服务
            foreach ($s_dir as $key => $dir) {
                $pid = exec("cat {$dir}/server.pid");
                $stat = exec(__DIR__ . '/' . $key . ' status');
                msgToClient($fd, 'success', ['msg' => $stat]);
                msgToClient($fd, 'qing', ['msg' => $stat . "，pid " . $pid]);
            }
            break;
    }
});

$server->on('message', function ($server, $frame) use ($s_dir) {
    $fd = $frame->fd;
    $data = $frame->data;
    if (key_exists($data, $s_dir)) {
        // 重启服务
        $dir = $s_dir[$data];
        $pid = exec("cat {$dir}/server.pid");
        msgToClient($fd, 'qing', ['msg' => "正在重启{$pid}……"]);
        exec("kill {$pid} > /dev/null 2>&1 &");

        // 等待1秒，获取新进程pid
        sleep(2);
        $pid = exec("cat {$dir}/server.pid");
        msgToClient($fd, 'qing', ['msg' => "启动完成"]);
        msgToClient($fd, 'qing', ['msg' => "新进程{$pid}"]);
    }
});

$server->on('close', function ($server, $fd) {
    // 删除队列中的fd
    $stat_fd = $server->storage->get('stat/fd2');
    if ($stat_fd) {
        $key = array_search($fd, $stat_fd);
        array_splice($stat_fd, $key, 1);
        $server->storage->set('stat/fd2', $stat_fd);
    }
});

$server->on('WorkerStart', function ($server, $worker_id) {
    global $storage;
    $server->storage = $storage;

    if ($worker_id == 0) {
        echo "服务启动成功，运行参数：\n";
        print_r($server->setting); // 打印运行参数

        // 清除fd
        if ($server->storage->exists('stat/fd2')) {
            $server->storage->del('stat/fd2');
        }
    }
});

$server->on('task', function ($server, $task_id, $src_worker_id, $data) {
    switch ($data['type']) { // 任务类型
        // 广播状态消息
        case 'stat_broadcast':
            stat_broadcast($data['msg']);
            break;

        default:
    }
});

$server->on('finish', function ($server, $task_id, $data) {

});

$server->start();
